/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.cef.generator.repository.entity;

import com.inspur.edp.caf.generator.BaseGenerator;
import com.inspur.edp.caf.generator.baseInfo.AnnotationInfo;
import com.inspur.edp.caf.generator.baseInfo.AnnotationType;
import com.inspur.edp.caf.generator.baseInfo.TypeInfo;
import com.inspur.edp.caf.generator.method.ClassMethodGenerator;
import com.inspur.edp.cef.api.attr.ChildAssemblerAttribute;
import com.inspur.edp.cef.gencommon.MediateType;
import com.inspur.edp.cef.generator.repository.base.CefRepoGenCtx;
import com.inspur.edp.cef.generator.repository.base.assemblerGenerator.DataTypeAssemblerGenerator;
import com.inspur.edp.cef.generator.repository.entity.methods.GetDefaultFilterConditionMethodGenerator;
import com.inspur.edp.cef.generator.repository.entity.methods.GetDefaultSortConditionMethodGenerator;
import com.inspur.edp.cef.generator.repository.entity.methods.InitColumnInfoMethodGenerator;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import lombok.var;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TypeLiteral;

import java.util.ArrayList;

public abstract class EntityAssmeblerGenerator extends DataTypeAssemblerGenerator {
    protected IGspCommonObject cmObject;
//    private CefRepoGenCtx repoGenCtx;

    public EntityAssmeblerGenerator(CefRepoGenCtx repoGenCtx, IGspCommonObject dataType) {
        super(repoGenCtx, dataType);
        this.repoGenCtx = repoGenCtx;
        this.cmObject = dataType;
    }

    @Override
    protected TypeInfo setParentClass() {
        TypeInfo typeInfo = new TypeInfo("EntityAssembler");
        typeInfo.setTypePackageName("com.inspur.edp.cef.repository.assembler.entity");
        return typeInfo;
    }

    @Override
    protected void beforeInitialize() {
        super.beforeInitialize();
        repoGenCtx
                .getEntityAssemblers()
                .put(cmObject.getCode(), new MediateType(repoGenCtx.getDefaultNameSpace(), getName()));
    }

    @Override
    protected ArrayList<AnnotationInfo> getAttributeList() {

        ArrayList<AnnotationInfo> list = super.getAttributeList();
        if (list == null) {
            list = new java.util.ArrayList<AnnotationInfo>();
        }

        for (IGspCommonObject item : cmObject.getContainChildObjects()) {
            list.add(getChildObjAssemblerAttribute(item.getCode()));
        }
        return list;
    }

    private AnnotationInfo getChildObjAssemblerAttribute(String objectCode) {
        AnnotationInfo info = new AnnotationInfo();
        TypeInfo typeInfo = new TypeInfo("ChildAssemblerAttribute");
        typeInfo.setTypePackageName("com.inspur.edp.cef.api.attr");
        info.setTypeInfo(typeInfo);
        info.setAnnotationType(AnnotationType.Normal);

        StringLiteral param1 = ast.newStringLiteral();
        param1.setLiteralValue(objectCode);
        TypeLiteral param2 = ast.newTypeLiteral();
        param2.setType(ast.newSimpleType(
                ast.newSimpleName(repoGenCtx.getEntityAssemblers().get(objectCode).getClassName())));

        info.getParams().put("nodeCode", param1);
        info.getParams().put("assemblerType",param2);

        return info;
    }

//    protected final java.util.ArrayList<SyntaxNodeOrToken> getAttributeArguments(String objCode) {
//        java.util.ArrayList<SyntaxNodeOrToken> argumentList =
//                new java.util.ArrayList<SyntaxNodeOrToken>(
//                        java.util.Arrays.asList(
//                                new SyntaxNodeOrToken[]{
//                                        SyntaxFactory.AttributeArgument(
//                                                SyntaxFactory.LiteralExpression(
//                                                        SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(objCode))),
//                                        SyntaxFactory.Token(SyntaxKind.CommaToken),
//                                        SyntaxFactory.AttributeArgument(
//                                                SyntaxFactory.TypeOfExpression(
//                                                        SyntaxFactory.IdentifierName(
//                                                                repoGenCtx.getEntityAssemblers().get(objCode).getClassName())))
//                                }));
//        return argumentList;
//    }

    @Override
    protected ArrayList<BaseGenerator> createClassExtendChildGenrators() {
        ArrayList<BaseGenerator> list = super.createClassExtendChildGenrators();
        if (list == null) {
            list = new java.util.ArrayList<BaseGenerator>();
        }
        addChildEntityAssGenerators(list);
        return list;
    }

    private void addChildEntityAssGenerators(java.util.ArrayList<BaseGenerator> list) {
        for (IGspCommonObject item : cmObject.getContainChildObjects()) {
            list.add(createChildEntityAssGenerator(item));
        }
    }

    protected abstract EntityAssmeblerGenerator createChildEntityAssGenerator(
            IGspCommonObject childObject);


    // region MethodGenerators
    @Override
    protected ArrayList<ClassMethodGenerator> createMethodGenerators() {
        ArrayList<ClassMethodGenerator> list = super.createMethodGenerators();
        if (list == null) {
            list = new ArrayList<ClassMethodGenerator>();
        }
        list.add(getInitColumnMethodGenerator());
        // list.add(getInitAssMethodGenerator());
        list.add(getFilterMethodGenerator());
        list.add(getSortMethodGenerator());
        return list;
    }

    protected abstract InitColumnInfoMethodGenerator getInitColumnMethodGenerator();

    // protected virtual InitAssociationInfoMethodGenerator  getInitAssMethodGenerator()
    // {
    //    return new InitAssociationInfoMethodGenerator(base.Context, cmObject.getIsRef());
    // }
    protected GetDefaultFilterConditionMethodGenerator getFilterMethodGenerator() {
        return new GetDefaultFilterConditionMethodGenerator(getContext());
    }

    protected GetDefaultSortConditionMethodGenerator getSortMethodGenerator() {
        return new GetDefaultSortConditionMethodGenerator(getContext());
    }

    @Override
    protected void afterGenerate() {
        super.afterGenerate();
        if (cmObject.getParentObject() == null) {
            repoGenCtx.setRootEntityAssemblerType(new MediateType(this.getContext().getRepoGenCtx().getPackageName(), getName()));
            repoGenCtx.getCefGenCtx().setRootRepositoryType(new MediateType(this.getContext().getRepoGenCtx().getPackageName(), getName()));
        }
    }
    // endregion MethodGenerators
}
